package com.xdf.whiteaccount.taskservice.impl;

import com.xdf.whiteaccount.config.datasource.DynamicDataSource;
import com.xdf.whiteaccount.config.task.DynamicTaskConfig;
import com.xdf.whiteaccount.dao.PlanMapper;
import com.xdf.whiteaccount.dao.SysConfigIntMapper;
import com.xdf.whiteaccount.entity.SysConfigInt;
import com.xdf.whiteaccount.enums.ConfigIntEnum;
import com.xdf.whiteaccount.enums.DatasourceKey;
import com.xdf.whiteaccount.taskservice.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;

/**
 * @program: white-account
 * @description: 定时自动审核
 * @author: 张柯
 * @create: 2021-07-26 14:36
 **/
@Service
@Slf4j
public class TaskServiceImpl implements TaskService {
    private static final String TASK_PREFIX = "AUTO_AUDIT_TASK:";
    @Autowired
    private DynamicTaskConfig taskConfig;
    @Autowired
    private PlanMapper planMapper;
    @Autowired
    private SysConfigIntMapper sysConfigIntMapper;

    /**
     * 定时审核全部
     * 每小时检测配置
     */
    @Scheduled(cron = "0 0 0/1 * * ? ")
//    @Scheduled(cron = "0/5 0/1 * * * ? ")
    @Override
    public void autoAudit() {
        List<String> keys = getDataSourceKeys();
        DynamicDataSource dataSource = DynamicDataSource.getInstance();
        log.warn("开始注册任务！");
        for (String key : keys) {
            if (!DatasourceKey.PRIMARY_KEY.equals(key)) {
                //  添加所有账套的定时功能
                String taskName = getKey(key);
                String currentKey = dataSource.getCurrentDataSourceName();
                dataSource.switchDataSource(key);
                SysConfigInt configInt = sysConfigIntMapper.selectByPrimaryKey(ConfigIntEnum.AUTO_AUDIT_AT.getField());
                Integer _value = Optional.ofNullable(configInt).map(SysConfigInt::getConfigValue).orElse(0);
                dataSource.switchDataSource(currentKey);
                if (_value == 0) {
                    taskConfig.stopTask(taskName);
                    continue;
                }
                //  定义任务
                Runnable r = () -> {
                    try {
                        //  执行方法
                        dataSource.switchDataSource(key);
                        planMapper.auditAll();
                        log.warn("自动一键审核执行完成。当前账套：{}", key);
                    } catch (Exception e) {
                        //  出错！
                        e.printStackTrace();
                        log.error("自动一键审核执行过程中出现错误。当前账套：{}", key);
                        log.error(e.getMessage());
                    } finally {
                        dataSource.switchDataSource(currentKey);
                    }
                };
                //  定义cron
                String cron = cronExpressGen(_value);
                boolean success;
                //  更新或者新增任务
                if (!Optional.ofNullable(taskConfig.getCron(taskName)).orElse("").equals(cron)) {
                    success = taskConfig.updateTask(taskName, r, cron);
                } else {
                    success = taskConfig.addTask(taskName, r, cron);
                }
                if (!success) {
                    log.error("创建定时计划任务失败，任务名：{}", taskName);
                }
            }
        }
    }

    /**
     * 获取所有账套key
     *
     * @return
     */
    private List<String> getDataSourceKeys() {
        DynamicDataSource dataSource = DynamicDataSource.getInstance();
        return dataSource.getDataSourceKeys();
    }

    /**
     * 生成任务key
     *
     * @param databaseKey
     * @return
     */
    private String getKey(String databaseKey) {
        return TASK_PREFIX + databaseKey;
    }

    /**
     * 生成cron表达式
     *
     * @param hour
     * @return
     */
    private String cronExpressGen(Integer hour) {
        if (hour == 24 || hour < 0) {
            hour = 0;
        } else if (hour > 24) {
            hour = 23;
        }
        return "0 0 " + hour + " * * ? ";
    }
}
